import java.awt.*;
import java.awt.event.*;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import javax.swing.*;

public class ICalCreator implements ItemListener{
    JPanel cards; //a panel that uses CardLayout
    final static String NEWEVENT = "Create New Event";
    final static String CREATEDEVENTS = "View Events Created";
    String EVENTTITLE, EVENTLOCATION, EVENTSUMMARY, EVENTRESOURCES = " ";
    ArrayList<Event> ArrayEvents = new ArrayList<Event>();
    String inputFreq = "";
    
	public void addComponentToPane(Container pane) {
        //Put the JComboBox in a JPanel to get a nicer look.
        JPanel comboBoxPane = new JPanel(); //use FlowLayout
        String comboBoxItems[] = { NEWEVENT, CREATEDEVENTS };
        JComboBox cb = new JComboBox(comboBoxItems);
        cb.setEditable(false);
        cb.addItemListener(this);
        comboBoxPane.add(cb);
        
        //Create the "cards".
        JPanel events = new JPanel();
        final JTextArea listedEvents = new JTextArea("None", 10, 55);
        listedEvents.setEditable(false);
        events.add(listedEvents);
        JButton generate = new JButton("Generate ics file");
        events.add(generate);
        JButton remove = new JButton("Remove events");
        events.add(remove);
        remove.addActionListener(new ActionListener()
        {
			public void actionPerformed(ActionEvent arg0) 
			{
				if(ArrayEvents.size() == 0)
				{
					JFrame noEvents = new JFrame("No Events!");
					JOptionPane.showMessageDialog(noEvents, "There are no events!");
				}
				else
				{
					for(int i = 0; i < ArrayEvents.size(); i++)
					{
						ArrayEvents.remove(i);
					}
					listedEvents.setText("none");
					JFrame deleted = new JFrame("Deleted!");
					JOptionPane.showMessageDialog(deleted, "All events were deleted!");
				}
			}
        	
        });
        generate.addActionListener(new ActionListener()
        		{
					public void actionPerformed(ActionEvent arg0) 
					{
						String prefix = "BEGIN:VCALENDAR" + "\n" +
	        			        "VERSION:2.0" + "\n" +
	        			        "BEGIN:VEVENT" + "\n";
						String suffix = "END:VEVENT" + "\n" +
						        "END:VCALENDAR";
						try 
						{
							//replace File args to specify directory path
							File f = new File("/Users/ryan_email/Desktop/ical.ics");
							FileWriter fstream = new FileWriter(f);
							BufferedWriter out = new BufferedWriter(fstream);
							out.write(prefix);
							for(int i = 0; i < ArrayEvents.size(); i++)
							{
								out.write(ArrayEvents.get(i).evtIcs());
							}
							out.write(suffix);
							out.close();
						} 
						catch (IOException e) 
						{
							e.printStackTrace();
						}
						JFrame gen = new JFrame("Generated");
						JOptionPane.showMessageDialog(gen, "ics File was generated!");
					}
        		});
        
        final JPanel EFormTEXT = new JPanel();
        final JTextField etitle = new JTextField(20);
        final JTextField elocation = new JTextField(20);
        final JTextField ecomments = new JTextField(20);
        final JTextField eresources = new JTextField(20);
        EFormTEXT.add(new JLabel("Event Title:"));
        EFormTEXT.add(etitle);
        EFormTEXT.add(new JLabel("Event Location:"));
        EFormTEXT.add(elocation);
        EFormTEXT.add(new JLabel("Comments:"));
        EFormTEXT.add(ecomments);
        EFormTEXT.add(new JLabel("Resources: "));
        EFormTEXT.add(eresources);
       
        EFormTEXT.add(new JLabel("Start Date:"));
        String monthItems[] = {"01", "02", "03", "04", "05", 
        		"06", "07", "08", "09", "10", "11",
        		"12"};
        final JComboBox monthsSTART = new JComboBox(monthItems);
        monthsSTART.setEditable(false);
        EFormTEXT.add(monthsSTART);
        
        final String DAYS_28[] = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10",
        		"11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
        		"21", "22", "23", "24", "25", "26", "27", "28"};
        final String DAYS_30[] = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10",
        		"11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
        		"21", "22", "23", "24", "25", "26", "27", "28", "29", "30"};
        final String DAYS_31[] = {"01", "02", "03", "04", "05", "06", "07", "08", "09", "10",
        		"11", "12", "13", "14", "15", "16", "17", "18", "19", "20",
        		"21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"};
        
        final JComboBox daysSTART = new JComboBox(DAYS_31);
        daysSTART.setEditable(false);
        EFormTEXT.add(daysSTART);

        monthsSTART.addItemListener(new ItemListener()
        {
        	public void itemStateChanged(ItemEvent evt) 
        	{
        		int input = Integer.parseInt((String)evt.getItem());
        		if(input == 2)
        		{
        			JComboBox days28 = new JComboBox(DAYS_28);
        			daysSTART.setModel(days28.getModel());
        		}
        		else if(input == 4 || input == 6 || input == 9 || input == 11)
        		{
        			JComboBox days30 = new JComboBox(DAYS_30);
        			daysSTART.setModel(days30.getModel());
        		}
        		else
        		{
        			JComboBox days31 = new JComboBox(DAYS_31);
        			daysSTART.setModel(days31.getModel());
        		}
        	}
        });
        
        String years[] = {"2013", "2014", "2015", "2016", "2017", "2018"};
        final JComboBox yearSTART = new JComboBox(years);
        yearSTART.setEditable(false);
        EFormTEXT.add(yearSTART);
        EFormTEXT.add(new JLabel("Start Time:"));
        String hours[] = {"01", "02", "03", "04", "05", "06", "07",
        		"08", "09", "10", "11", "12" , "13", "14", "15", "16", "17",
        		"18", "19", "20", "22", "23", "24"};
        String mins[] = {"00", "15", "30", "45"};
        final JComboBox HOURSTART = new JComboBox(hours);
        HOURSTART.setEditable(false);
        final JComboBox MINSTART = new JComboBox(mins);
        MINSTART.setEditable(false);
        EFormTEXT.add(HOURSTART);
        EFormTEXT.add(MINSTART);
        
        
        final JLabel endDate = new JLabel("End Date:");
        EFormTEXT.add(endDate);
        final JComboBox monthsEND = new JComboBox(monthItems);
        monthsEND.setEditable(false);
        EFormTEXT.add(monthsEND);
        
        final JComboBox daysEND = new JComboBox(DAYS_31);
        daysEND.setEditable(false);
        EFormTEXT.add(daysEND);
        
        monthsEND.addItemListener(new ItemListener()
        {
        	public void itemStateChanged(ItemEvent evt) 
        	{
        		int input = Integer.parseInt((String)evt.getItem());
        		if(input == 2)
        		{
        			JComboBox days28 = new JComboBox(DAYS_28);
        			daysEND.setModel(days28.getModel());
        		}
        		else if(input == 4 || input == 6 || input == 9 || input == 11)
        		{
        			JComboBox days30 = new JComboBox(DAYS_30);
        			daysEND.setModel(days30.getModel());
        		}
        		else
        		{
        			JComboBox days31 = new JComboBox(DAYS_31);
        			daysEND.setModel(days31.getModel());
        		}
        	}
        });
        
        final JComboBox yearEND = new JComboBox(years);
        yearEND.setEditable(false);
        EFormTEXT.add(yearEND);
        final JLabel endTime = new JLabel("End Time:");
        EFormTEXT.add(endTime);
        final JComboBox HOUREND = new JComboBox(hours);
        HOUREND.setEditable(false);
        final JComboBox MINEND = new JComboBox(mins);
        MINEND.setEditable(false);
        EFormTEXT.add(HOUREND);
        EFormTEXT.add(MINEND);
        
        EFormTEXT.add(new JLabel("Recurring Event?"));
        final JCheckBox yesButton;
        yesButton = new JCheckBox("Yes");
        yesButton.setSelected(false);
        EFormTEXT.add(yesButton);

		
        String rec[] = {"None", "DAILY", "MONTHLY", "YEARLY"};
		final JComboBox frequency = new JComboBox(rec);
		frequency.setEditable(false);
		frequency.setVisible(false);
		EFormTEXT.add(frequency);
		
		final JLabel until = new JLabel("Until:");
		until.setVisible(false);
		EFormTEXT.add(until);
		
		final JComboBox monthRec = new JComboBox(monthItems);
		monthRec.setEditable(false);
		monthRec.setVisible(false);
		EFormTEXT.add(monthRec);
		
		final JComboBox daysRec = new JComboBox(DAYS_31);
        daysRec.setEditable(false);
        daysRec.setVisible(false);
        EFormTEXT.add(daysRec);
        
        monthRec.addItemListener(new ItemListener()
        {
        	public void itemStateChanged(ItemEvent evt) 
        	{
        		int input = Integer.parseInt((String)evt.getItem());
        		if(input == 2)
        		{
        			JComboBox days28 = new JComboBox(DAYS_28);
        			daysRec.setModel(days28.getModel());
        		}
        		else if(input == 4 || input == 6 || input == 9 || input == 11)
        		{
        			JComboBox days30 = new JComboBox(DAYS_30);
        			daysRec.setModel(days30.getModel());
        		}
        		else
        		{
        			JComboBox days31 = new JComboBox(DAYS_31);
        			daysRec.setModel(days31.getModel());
        		}
        	}
        });
        
		final JComboBox yearRec = new JComboBox(years);
		yearRec.setVisible(false);
		yearRec.setEditable(false);
		EFormTEXT.add(yearRec);

        yesButton.addItemListener(new ItemListener()
        {
			public void itemStateChanged(ItemEvent arg0) 
			{
				if(yesButton.isSelected())
				{
					frequency.setVisible(true);
					until.setVisible(true);
					monthRec.setVisible(true);
					daysRec.setVisible(true);
					yearRec.setVisible(true);
				}
				else if(!yesButton.isSelected())
				{
					yesButton.setSelected(false);
					frequency.setVisible(false);
					until.setVisible(false);
					monthRec.setVisible(false);
					daysRec.setVisible(false);
					yearRec.setVisible(false);
				}
			}       	
        });

        JButton subTEXT = new JButton("Create Event");
        EFormTEXT.add(subTEXT);
        //Create the panel that contains the "cards".
        cards = new JPanel(new CardLayout());
        cards.add(EFormTEXT, NEWEVENT);
        cards.add(events, CREATEDEVENTS);
        
        pane.add(comboBoxPane, BorderLayout.PAGE_START);
        pane.add(cards, BorderLayout.CENTER);
        
        subTEXT.addActionListener(new ActionListener()
        {
			public void actionPerformed(ActionEvent action) 
			{
				String ys = yearSTART.getSelectedItem() + "";
		        String ms = monthsSTART.getSelectedItem() +"";
		        String ds = daysSTART.getSelectedItem() + "";
		        String hs = HOURSTART.getSelectedItem() +"";
		        String minS = MINSTART.getSelectedItem() +"";
		        final iCalDate startDate = new iCalDate(ys, ms, ds, hs, minS);
		        
		        String ye = yearEND.getSelectedItem() + "";
		        String me = monthsEND.getSelectedItem() +"";
		        String de = daysEND.getSelectedItem() + "";
		        String he = HOUREND.getSelectedItem() + "";
		        String mine = MINEND.getSelectedItem() + "";
		        final iCalDate endDate = new iCalDate(ye, me, de, he, mine);
				
		        if(!yesButton.isSelected())
		        {
			        if(startDate.compareTo(endDate) < 0)
					{
						JFrame frame = new JFrame("Warning!");
						JOptionPane.showMessageDialog(frame,
							    "End time was before start time.");
					}
			        else
			        {
			        	listedEvents.setText(null);
						EVENTTITLE = etitle.getText();
						EVENTLOCATION = elocation.getText();
						EVENTSUMMARY = ecomments.getText();
				        EVENTRESOURCES = eresources.getText();
						Event e = new Event(EVENTTITLE, EVENTLOCATION, EVENTSUMMARY, 
								EVENTRESOURCES,startDate, endDate);
						ArrayEvents.add(e);
						for(int i = 0; i < ArrayEvents.size(); i++)
						{
							listedEvents.append("\n" + (i+1 +") ") + ArrayEvents.get(i).toString());
						}
						etitle.setText(null);
						elocation.setText(null);
						ecomments.setText(null);
						eresources.setText(null);
						
						JFrame added = new JFrame("Done!");
						JOptionPane.showMessageDialog(added, "Added Event!");
			        }
		        }
		        else
		        {

			        String ry = yearRec.getSelectedItem() + "";
				    String rm = monthRec.getSelectedItem() +"";
				    String rd = daysRec.getSelectedItem() + "";
				    inputFreq = frequency.getSelectedItem() + "";
				    final iCalDate recEndDate = new iCalDate(ry,rm,rd,he,mine);
				        
				    listedEvents.setText(null);
				    EVENTTITLE = etitle.getText();
					EVENTLOCATION = elocation.getText();
					EVENTSUMMARY = ecomments.getText();
				    EVENTRESOURCES = eresources.getText();
				        
				    Event e = new Event(EVENTTITLE, EVENTLOCATION, EVENTSUMMARY, 
				    		EVENTRESOURCES,startDate, endDate, recEndDate, inputFreq);
					ArrayEvents.add(e);
					for(int i = 0; i < ArrayEvents.size(); i++)
					{
						listedEvents.append("\n" + (i+1 +") ") + ArrayEvents.get(i).toString());
					}
					etitle.setText(null);
					elocation.setText(null);
					ecomments.setText(null);
					eresources.setText(null);
					JFrame added = new JFrame("Done!");
					JOptionPane.showMessageDialog(added, "Added Event!");
			    }	        
			}
        });
	}
    public void itemStateChanged(ItemEvent evt) {
        CardLayout cl = (CardLayout)(cards.getLayout());
        cl.show(cards, (String)evt.getItem());
    }
    
    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event dispatch thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("iCal Creator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        //Create and set up the content pane.
        ICalCreator demo = new ICalCreator();
        demo.addComponentToPane(frame.getContentPane());
        
        //Display the window.
        frame.pack();
        frame.setSize(700, 400);
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        
        //Schedule a job for the event dispatch thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
    public class iCalDate
    {
    	private String month, day, year, hour, minute = " ";
    	
    	public iCalDate(String y, String mon, String d, String h, String min)
    	{
    		month = mon;
    		day = d;
    		year = y;
    		hour = h;
    		minute = min;
    	}
    	
    	public iCalDate() {
			// Default constructor
		}

		public String getMonth()
    	{
    		return month;
    	}
    	
    	public String getDay()
    	{
    		return day;
    	}
    	
    	public String getYear()
    	{
    		return year;
    	}
    	
    	public String getHour()
    	{
    		return hour;
    	}
    	
    	public String getMin()
    	{
    		return minute;
    	}
    	
    	public int compareTo(iCalDate e)
    	{
    		if(Integer.parseInt(e.getYear()) < 
    				Integer.parseInt(this.getYear()))
    		{
    			return -1;
    		}
    		else if(Integer.parseInt(e.getMonth()) < 
    				Integer.parseInt(this.getMonth()))
    		{
    			return -1;
    		}
    		else if(Integer.parseInt(e.getDay())
    				< Integer.parseInt(this.getDay()))
    		{
    			return -1;
    		}
    		else if(Integer.parseInt(e.getHour()) < 
    				Integer.parseInt(this.getHour()))
    		{
    			return -1;
    		}
    		/**
    		 * if statement to catch if ending minute was before starting minute
    		 * 00 is the exception because if the ending hour is greater than
    		 * the starting hour, the minutes can be 00. But otherwise the ending
    		 * minutes need to be > the starting minutes.
    		 */
    		else if(Integer.parseInt(e.getHour())
    				> Integer.parseInt(this.getHour()))
    		{
    			if(Integer.parseInt(e.getMin()) == 0 || Integer.parseInt(e.getMin()) == 
    					Integer.parseInt(this.getMin()))
    			{
    				return 1;
    			}
    			else
    			{
    				return -1;
    			}
    		}
    		else
    		{
    			return 1;
    		}
    	}
    }
    
    public class Event
    {
    	private String summary, location, comments, resources, frequency = "";
    	private iCalDate start = new iCalDate();
    	private iCalDate end = new iCalDate();
    	private iCalDate recEnd = new iCalDate();
    	String months[] = {"--","January", "February", "March", "April", "May",
    			"June", "July", "August", "September", "October", "November", "December"};
  		
    	public Event(String sum, String loc, String c, String r, iCalDate s, iCalDate e)
    	{
    		summary = sum;
    		location = loc;
    		comments = c;
    		resources = r;
    		start = s;
    		end = e;
    	}
    	
    	public Event(String sum, String loc, String c, String r, iCalDate s, iCalDate e,
    			iCalDate rec, String f)
    	{
    		summary = sum;
    		location = loc;
    		comments = c;
    		resources = r;
    		start = s;
    		end = e;
    		frequency = f;
    		recEnd = rec;
    	}
    	
    	public boolean isRecurring()
    	{
    		if(this.frequency.equalsIgnoreCase("None") || this.frequency.isEmpty())
    		{
    			return false;
    		}
    		else
    		{
    			return true;
    		}
    	}
    	
    	public String evtIcs()
    	{
    		String ics = "";
    		if(!this.isRecurring())
    		{
        		ics =   "CLASS:" + "PUBLIC" + "\n" +
                        "SUMMARY:" + summary + "\n" +
                        "COMMENT:" + comments + "\n" +
                        "LOCATION:" + location + "\n" +
                        "RESOURCES:" + resources + "\n" +
                        "DTSTART;TZID=Pacific/Honolulu:" + start.getYear() + start.getMonth() + start.getDay() + "T" + start.getHour() + start.getMin() + "00" + "Z" + "\n" +
                        "DTEND;TZID=Pacific/Honolulu:" + end.getYear() + end.getMonth() + end.getDay() + "T" + end.getHour() + end.getMin() + "00" + "Z" + "\n";
        		return ics;
    		}
    		else
    		{
    			String recurr = " ";
    			if(this.frequency.compareToIgnoreCase("YEARLY")==0)
    			{
    				recurr = "FREQ=YEARLY;UNTIL=" + recEnd.getYear() + recEnd.getMonth() + recEnd.getDay();;
    				ics =
    				"CLASS:" + "PUBLIC" + "\n" +
                    "SUMMARY:" + summary + "\n" +
                    "COMMENT:" + comments + "\n" +
                    "LOCATION:" + location + "\n" +
                    "RESOURCES:" + resources + "\n" +
                    "DTSTART;TZID=Pacific/Honolulu:" + start.getYear() + start.getMonth() + start.getDay() + "T" + start.getHour() + start.getMin() + "00" + "Z" + "\n" +
                    "DTEND;TZID=Pacific/Honolulu:" + end.getYear() + end.getMonth() + end.getDay() + "T" + end.getHour() + end.getMin() + "00" + "Z" + "\n" +
                    "RRULE:" + recurr + "\n";
    				return ics;
    			}
    			else if(this.frequency.compareToIgnoreCase("MONTHLY")==0)
    			{
    				recurr = "FREQ=MONTHLY;UNTIL=" + recEnd.getYear() + recEnd.getMonth() + recEnd.getDay();
    				ics =   "CLASS:" + "PUBLIC" + "\n" +
                            "SUMMARY:" + summary + "\n" +
                            "COMMENT:" + comments + "\n" +
                            "LOCATION:" + location + "\n" +
                            "RESOURCES:" + resources + "\n" +
                            "DTSTART;TZID=Pacific/Honolulu:" + start.getYear() + start.getMonth() + start.getDay() + "T" + start.getHour() + start.getMin() + "00" + "Z" + "\n" +
                            "DTEND;TZID=Pacific/Honolulu:" + end.getYear() + end.getMonth() + end.getDay() + "T" + end.getHour() + end.getMin() + "00" + "Z" + "\n" +
                            "RRULE:" + recurr + "\n";
        			return ics;
    			}
    			else if(this.frequency.compareToIgnoreCase("DAILY")==0)
    			{
    				recurr = "FREQ=DAILY;UNTIL=" + recEnd.getYear() + recEnd.getMonth() + recEnd.getDay();
    				ics =   "CLASS:" + "PUBLIC" + "\n" +
                            "SUMMARY:" + summary + "\n" +
                            "COMMENT:" + comments + "\n" +
                            "LOCATION:" + location + "\n" +
                            "RESOURCES:" + resources + "\n" +
                            "DTSTART;TZID=Pacific/Honolulu:" + start.getYear() + start.getMonth() + start.getDay() + "T" + start.getHour() + start.getMin() + "00" + "Z" + "\n" +
                            "DTEND;TZID=Pacific/Honolulu:" + end.getYear() + end.getMonth() + end.getDay() + "T" + end.getHour() + end.getMin() + "00" + "Z" + "\n" +
                            "RRULE:" + recurr + "\n";
    				return ics;
    			}
    			else
    			{
    				return ics;
    			}
    		}
    	}
    	
    	public String toString()
    	{
    		String result = " ";
    		if(this.isRecurring())
    		{
    			result = summary + " at " + location + " [" + comments + "] on " + months[Integer.parseInt(start.getMonth())] + " " + start.getDay() + ", " + start.getYear()
    	        		+ " at " + start.getHour() + start.getMin() + " recurring " + this.frequency +
    	        		" until: " + months[Integer.parseInt(recEnd.getMonth())] + " " + recEnd.getDay() + ", " + recEnd.getYear();
    	        		return result;
    		}
    		else
    		{
    			result = summary + " at " + location + " [" + comments + "] on " + months[Integer.parseInt(start.getMonth())] + " " + start.getDay() + ", " + start.getYear()
        		+ " at " + start.getHour() + start.getMin() + " to " + 
        		months[Integer.parseInt(end.getMonth())] + " " + end.getDay() + ", " + end.getYear()
        		+ " at " + end.getHour() + end.getMin();
        		return result;
    		}
    	}
    }
}
